package com.easylinkin.sm.context;

import static site.morn.framework.context.CommonConstant.Caches.USER;

import java.util.Collections;
import java.util.Objects;
import java.util.Optional;

import javax.annotation.Resource;

import org.springframework.beans.BeanUtils;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

import com.easylinkin.sm.entity.User;
import com.easylinkin.sm.service.UserService;

import site.morn.bean.annotation.Objective;
import site.morn.cache.CacheGroup;
import site.morn.framework.context.AccountContext;
import site.morn.framework.context.UserContextProducer;

/**
 * 用户适配器
 *
 * @author timely-rain
 * @since 1.0.0, 2019/4/16
 */
@Component
@Objective
public class SmUserContextProducer implements UserContextProducer<User> {

  @Resource
  private UserService userService;

  @Override
  public User getCurrent() {
    String username = getCurrentUsername();
    CacheGroup cacheGroup = AccountContext.cacheGroup();
    return cacheGroup.get("USER_SM", username, () -> getUser(username));
  }

  @Override
  public String getCurrentUsername() {
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    return Optional.ofNullable(authentication).map(Authentication::getName).orElse(null);
  }

  /**
   * 获取指定用户
   *
   * <p>清空角色信息，避免缓存冗余数据
   *
   * @param username 用户名
   * @return 用户
   */
  private User getUser(String username) {
    User user = userService.findByUsername(username);
    if (Objects.isNull(user)) {
      return null;
    }
    User copy = new User();
    BeanUtils.copyProperties(user, copy);
    copy.setRoles(Collections.emptyList());
    return copy;
  }
}
